package com.zjb.demo.common.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * @author 庄佳彬
 * @since 2023/12/23 13:54
 */
public class CastUtils {

    /**
     * 从 FROM 强制转换为 TO
     *
     * @param from 原始数据
     * @param <TO> 转换后类型
     * @return 转换后数据
     * @throws ClassCastException 类型转换异常
     */
    @SuppressWarnings(value = {"unchecked"})
    public static <TO> TO cast(Object from) throws ClassCastException {
        return (TO) from;
    }

    /**
     * 从 FROM 利用TO.class#cast() 转换成 TO
     *
     * @param from    原始对象
     * @param toClass 目标类
     * @param <FROM>  原始类型
     * @param <TO>    目标类型
     * @return 转换后对象
     * @throws ClassCastException 类型转换异常
     */
    public static <FROM, TO> TO cast(FROM from, Class<TO> toClass) throws ClassCastException {
        if (from == null) {
            return cast(null);
        }
        Objects.requireNonNull(toClass, "目标类不能为null");
        return toClass.cast(from);
    }

    /**
     * 利用转换器 将 FROM 转换为TO
     *
     * @param from     原始对象
     * @param function 转换器
     * @param <FROM>   原始类型
     * @param <TO>     目标类型
     * @return 目标对象
     */
    public static <FROM, TO> TO cast(FROM from, Function<FROM, TO> function) {
        if (from == null) {
            return cast(null);
        }
        Objects.requireNonNull(function, "转换方法不能为null");
        return function.apply(from);
    }

    /**
     * 利用转换器 将 FROM 转换为TO
     * 如果from为null，返回 supplier.get()
     *
     * @param from     待转换值
     * @param function 转换器
     * @param supplier 默认值，当from为null，或function为null，或function执行失败时
     * @param <FROM>   原始类型
     * @param <TO>     目标类型
     * @return 转换后的值
     */
    public static <FROM, TO> TO cast(FROM from, Function<FROM, TO> function, Supplier<TO> supplier) {
        Objects.requireNonNull(supplier, "默认值获取不能为null");
        if (from == null) {
            return supplier.get();
        }
        try {
            return cast(from, function);
        } catch (Exception e) {
            return supplier.get();
        }
    }

    /**
     * 利用转换器转换Collection中的元素从FROM 转换到TO
     *
     * @param list     原始集合
     * @param function 元素转换器
     * @param <FROM>   原始类型
     * @param <TO>     目标类型
     * @return 转换后的List
     */

    public static <FROM, TO> List<TO> castList(Collection<FROM> list, Function<FROM, TO> function) {
        Objects.requireNonNull(list, "待转换集合不能为null");
        Objects.requireNonNull(function, "转换方法不能为null");
        return list.stream().collect(ArrayList::new,
                (r, t) -> r.add(function.apply(t)),
                ArrayList::addAll);
    }

}
